package com.itlong.cloud.controller.sdkV2.intercom.app;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.itlong.cloud.POJO.DTO.operate.OperateDeviceManageGetPageDTO;
import com.itlong.cloud.POJO.DTO.property.IotCloudIntercomStateDTO;
import com.itlong.cloud.POJO.DTO.sdk.CloudDeviceSDKDTO;
import com.itlong.cloud.POJO.VO.MessageVO;
import com.itlong.cloud.POJO.VO.SDKMessageVO;
import com.itlong.cloud.POJO.VO.app.AppTCPResultVO;
import com.itlong.cloud.POJO.VO.operate.OperateDeviceManageInfoAllVO;
import com.itlong.cloud.POJO.VO.operate.OperateDeviceManageInfoVO;
import com.itlong.cloud.POJO.VO.sdk.CloudTalkSDKServerUserCacheVO;
import com.itlong.cloud.PlatformConstants;
import com.itlong.cloud.annotation.UnAuthAccessRequired;
import com.itlong.cloud.common.network.ITCPServiceClient;
import com.itlong.cloud.constants.RedisConstant;
import com.itlong.cloud.enumerate.LanguageTypeEnum;
import com.itlong.cloud.enumerate.ecode.AppErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.BaseErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.CloudTalkErrorCodeEnum;
import com.itlong.cloud.enumerate.ecode.ErrorCode;
import com.itlong.cloud.enumerate.ecode_en.BaseErrorCodeEnumEN;
import com.itlong.cloud.enumerate.oldapp.Code;
import com.itlong.cloud.enumerate.oldapp.Message;
import com.itlong.cloud.equip.operate.IOperateDeviceManageServiceClient;
import com.itlong.cloud.equip.property.ICloudIntercomServiceClient;
import com.itlong.cloud.service.RedisService;
import com.itlong.cloud.thrown.DataAccessException;
import com.itlong.cloud.user.app.IAppOldServeServiceClient;
import com.itlong.cloud.user.sdk.ICloudTalkSDKServerUserServiceClient;
import com.itlong.cloud.utils.encrypt.DesEncryptUtil;
import com.itlong.cloud.utils.encrypt.Md5EncryptUtil;
import com.itlong.cloud.utils.node.JsonUtil;
import com.itlong.cloud.utils.page.Page;
import com.itlong.cloud.utils.words.StringHandlerUtil;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.net.URLDecoder;
import java.util.*;

/**
 * <desc>
 * 云对讲app端控制器
 * </desc>
 *
 * @createDate 2019/09/20
 */
@Controller
@RequestMapping("/sdk/cloud/intercom/app")
public class SDKCloudTalkAppController {
    //日志记录对象
    private static final Logger LOG = LoggerFactory.getLogger(SDKCloudTalkAppController.class);

    @Autowired
    IAppOldServeServiceClient iAppOldServeServiceClient;

    @Autowired
    ICloudTalkSDKServerUserServiceClient iCloudTalkSDKServerUserServiceClient;

    @Autowired
    ICloudIntercomServiceClient iCloudIntercomServiceClient;

    @Autowired
    ITCPServiceClient itcpServiceClient;

    @Autowired
    IOperateDeviceManageServiceClient iOperateDeviceManageServiceClient;

    @Autowired
    private RedisService redisService;

    @Value("${" + PlatformConstants.APP_REQUEST_PARAMS_ENCRYPT_KEY + "}")
    public String APP_REQUEST_PARAMS_ENCRYPT_KEY;

    @Value("${" + PlatformConstants.CLOUD_TALK_SDK_AESKEY + "}")
    private String cloudTalkSdkAesKey; //AES加密KEY
    @Value("${" + PlatformConstants.CLOUD_TALK_SDK_MD5KEY + "}")
    private String cloudTalkSdkMd5Key;  //MD5加密KEY

    /**
     * <desc>
     * 云对讲SDK_获取SDK版本
     * </desc>
     *
     * @param type 应用接入凭证
     * @param sort 应用接入密钥
     * @return 标准格式化响应结果
     * @author Jiaqi.X
     * @createDate 2018/05/14
     */
    @ResponseBody
    @RequestMapping("/app/version")
    public Message getLatestApp(String type, String sort) {
        try {
            if (StringUtils.isEmpty(type) || StringUtils.isEmpty(sort)) {
                return new Message(Code.NOT_PARAM);
            }
            Message message = iAppOldServeServiceClient.getLatestApp(type, sort);
            return message;
        } catch (Exception e) {
            LOG.error(String.format("【云对讲SDK_APP_检测SDK版本】{type:%s sort:%s} exception:{%s}", type, sort, e));
            return new Message(Code.ERROR);
        }
    }

    /**
     * <desc>
     * SDK开发者认证
     * </desc>
     *
     * @param appid  应用接入凭证
     * @param secret 应用接入密钥
     * @return 标准格式化响应结果
     * @author Juguang.S
     * @createDate 2018/11/20
     */
    @ResponseBody
    @RequestMapping("/app/getToken")
    public Object getToken(String appid, String secret) {
        try {
            if (StringUtils.isEmpty(appid) || StringUtils.isEmpty(secret)) {
                return new MessageVO(BaseErrorCodeEnum.NOT_PARAM.getErrorCode());
            }

            //登陆校验及缓存更新
            CloudTalkSDKServerUserCacheVO userCacheVO = iCloudTalkSDKServerUserServiceClient.sdkAppLogin(appid, secret);
            if (userCacheVO == null) {
                return new MessageVO(CloudTalkErrorCodeEnum.SERVER_DEVELOP_ERR.getErrorCode());
            }
            JSONObject js = new JSONObject();
            js.put("token", userCacheVO.getToken());

            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), js);
        } catch (Exception e) {
            throw new DataAccessException("【云对讲SDK APP端认证_CloudTalkSDKAppServeController_getToken】APP端SDK认证异常", e);
        }
    }

    /**
     * <desc>
     * 请求参数进行加密
     * </desc>
     *
     * @return
     * @author Juguang.S
     * @createDate 2018/11/27
     */
    @PostMapping(path = "/app/paramsEncryption")
    @ResponseBody
    public Object paramsEncryption() {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            Map<String, String[]> map = request.getParameterMap();
            Map<String, String> mapresult = new HashMap<>();
            for (String str : map.keySet()) {
                //map.keySet()返回的是所有key的值
                String[] strresult = map.get(str);//得到每个key多对用value的值
                StringBuffer sb = new StringBuffer();

                for (int i = 0; i < strresult.length; i++) {
                    sb.append(strresult[i]);        //append String并不拥有该方法，所以借助StringBuffer
                }
                mapresult.put(str, sb.toString());
            }
            String encryptResult = DesEncryptUtil.aesEncrypt(JsonUtil.toJSON(mapresult), cloudTalkSdkAesKey, cloudTalkSdkMd5Key);

/*            String plusEncode = URLEncoder.encode("+", "UTF-8");
            encryptResult.replaceAll("\\+", plusEncode);*/

            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("encrypScript", encryptResult);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), resultMap);
        } catch (Exception e) {
            throw new DataAccessException("【云对讲SDK】请求参数进行加密失败", e);
        }
    }

    /**
     * <desc>
     * 返回结果进行解密
     * </desc>
     *
     * @return
     * @author Juguang.S
     * @createDate 2018/11/27
     */
    @PostMapping(path = "/app/responseDecrypt")
    @ResponseBody
    public Object responseDecrypt() {
        try {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            Map<String, String[]> map = request.getParameterMap();

            String content = StringHandlerUtil.replaceBlank(map.get("encrypScript")[0].toString().substring(0, map.get("encrypScript")[0].toString().length() - 32));
            String encryptResult = URLDecoder.decode(DesEncryptUtil.aesDecrypt(content, cloudTalkSdkAesKey), "UTF-8");
            Map<String, Object> params = JsonUtil.toObject(encryptResult, HashMap.class);
            return new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), params);
        } catch (Exception e) {
            throw new DataAccessException("【云对讲SDK】返回结果进行解密失败", e);
        }
    }

    /**
     * <desc>
     * SDK-app用户开门操作
     * <desc/>
     *
     * @param sipAccount sip帐号
     * @param message    指令相关信息
     * @return
     * @author Qiang.S
     * @createDate 2018-09-12
     */
    @ResponseBody
    @RequestMapping(value = "/appOpenDoor", method = RequestMethod.POST)
    @UnAuthAccessRequired
    public MessageVO appOpenDoor(String token, String language, String createTime, String sipAccount, String message, String sign) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        MessageVO messageVO;
        try {
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("createTime", createTime);
            params.put("language", language);
            params.put("sipAccount", sipAccount);
            params.put("message", message);
            //验证签名
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            //验证token
            if (StringUtils.isNotBlank(token)) {
                //解密token拿到用户信息  1代表APP开门音视频切换的token 2代表除此之外的token
                CloudTalkSDKServerUserCacheVO vo = iCloudTalkSDKServerUserServiceClient.retrieve(token, "1");
                if (vo == null) {
                    return new MessageVO(CloudTalkErrorCodeEnum.USER_TOKEN_ERROR.getErrorCode());
                }
            } else {
                return new MessageVO(CloudTalkErrorCodeEnum.USER_TOKEN_ERROR.getErrorCode());
            }
            if (StringUtils.isBlank(sipAccount) || StringUtils.isEmpty(message)) {
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? BaseErrorCodeEnum.NOT_PARAM.getErrorCode() : BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                return new MessageVO(errorCode);
            }
            String deviceUnique = iCloudIntercomServiceClient.getDeviceUniqueBySip(sipAccount);
            //iot不在线走tcp
            if (redisService.get(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY + deviceUnique) == null ||
                    !redisService.get(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY + deviceUnique).equals("2")) {
//                messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),itcpServiceClient.sendMessage("",sipAccount,message,10));
                return new MessageVO(AppErrorCodeEnum.CLOUD_TALK_IS_NOT_ONLINE_ERROR.getErrorCode());
            } else {//iot在线
                iCloudIntercomServiceClient.iotOpenDoor("", sipAccount, message, "1");
                int count = 0;
                AppTCPResultVO appTCPResultVO = new AppTCPResultVO();
                appTCPResultVO.setDataFlag("1");
                while (count < 10) {
                    Thread.sleep(500);
                    IotCloudIntercomStateDTO dto = JsonUtil.toObject(redisService.getKeysForDevice(RedisConstant.REDIS_IOT_CLOUD_INTERCOM_STATE_CACHE +
                            deviceUnique), IotCloudIntercomStateDTO.class);
                    if (dto != null && dto.getMsgCode() == 0) {
                        appTCPResultVO.setDataFlag("0");
                        redisService.del(RedisConstant.REDIS_IOT_CLOUD_INTERCOM_STATE_CACHE + deviceUnique);
                        break;
                    }
                    count++;
                }
                messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), appTCPResultVO);
            }
            return messageVO;
        } catch (Exception e) {
            throw new DataAccessException("【SDK_云对讲_appOpenDoor】开门异常", e);
        }
    }

    /**
     * <desc>
     * SDK-app切换音视频
     * <desc/>
     *
     * @param videoState 0：音视频1音频
     * @param sipAccount sip帐号
     * @return
     * @author Qiang.S
     * @createDate 2018-09-12
     */
    @RequestMapping(value = "/switchVideo", method = RequestMethod.POST)
    @ResponseBody
    @UnAuthAccessRequired
    public MessageVO switchVideo(String token, String videoState, String language, String createTime, String sipAccount, String sign) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        MessageVO messageVO;
        try {
            //验签
            Map<String, String> params = new HashMap<>();
            params.put("createTime", createTime);
            params.put("language", language);
            params.put("sipAccount", sipAccount);
            params.put("videoState", videoState);
            //验证签名
            if (!Md5EncryptUtil.checkAppSign(params, sign, APP_REQUEST_PARAMS_ENCRYPT_KEY)) {
                return new MessageVO(AppErrorCodeEnum.APP_SIGN_ERR.getErrorCode());
            }
            //验证token
            if (StringUtils.isNotBlank(token)) {
                //解密token拿到用户信息  1代表APP开门音视频切换的token 2代表除此之外的token
                CloudTalkSDKServerUserCacheVO vo = iCloudTalkSDKServerUserServiceClient.retrieve(token, "1");
                if (vo == null) {
                    return new MessageVO(CloudTalkErrorCodeEnum.USER_TOKEN_ERROR.getErrorCode());
                }
            } else {
                return new MessageVO(CloudTalkErrorCodeEnum.USER_TOKEN_ERROR.getErrorCode());
            }
            if (StringUtils.isBlank(sipAccount) || StringUtils.isBlank(videoState)) {
                ErrorCode errorCode = LanguageTypeEnum.CHINESE.getLanguage().equals(language) ? BaseErrorCodeEnum.NOT_PARAM.getErrorCode() : BaseErrorCodeEnumEN.NOT_PARAM.getErrorCode();
                return new MessageVO(errorCode);
            }
            String deviceUnique = iCloudIntercomServiceClient.getDeviceUniqueBySip(sipAccount);
            //iot不在线走tcp
            if (redisService.get(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY + deviceUnique) == null ||
                    !redisService.get(RedisConstant.DEVICE_INTERCOM_IS_ONLINE_KEY + deviceUnique).equals("2")) {
//                messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(),itcpServiceClient.sendMessage("",sipAccount,videoState, 11));
                return new MessageVO(AppErrorCodeEnum.CLOUD_TALK_IS_NOT_ONLINE_ERROR.getErrorCode());
            } else {//iot在线
                iCloudIntercomServiceClient.switchVideo(sipAccount, videoState);
                int count = 0;
                AppTCPResultVO appTCPResultVO = new AppTCPResultVO();
                appTCPResultVO.setDataFlag("1");
                appTCPResultVO.setVideoState("");
                while (count < 10) {
                    Thread.sleep(500);
                    IotCloudIntercomStateDTO dto = JsonUtil.toObject(redisService.getKeysForDevice(RedisConstant.REDIS_IOT_CLOUD_INTERCOM_STATE_CACHE +
                            deviceUnique), IotCloudIntercomStateDTO.class);
                    if (dto != null && dto.getMsgCode() == 0) {
                        appTCPResultVO.setDataFlag("0");
                        appTCPResultVO.setVideoState(dto.getVideoState());
                        redisService.del(RedisConstant.REDIS_IOT_CLOUD_INTERCOM_STATE_CACHE + deviceUnique);
                        break;
                    }
                    count++;
                }
                messageVO = new MessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), appTCPResultVO);
            }
            return messageVO;
        } catch (Exception e) {
            throw new DataAccessException("【SDK_云对讲_switchVideo】切换音视频异常", e);
        }
    }


  /*  *//**
     * <desc>
     * 获取设备在线状态 设备类型：1云对讲 3人脸平板  7一体式人脸识别仪
     * </desc>
     *
     * @Author chengshican
     * @Date 2020-09-23 19:09
     * @Param
     * @Return
     * @Exception
     *//*
    @UnAuthAccessRequired
    public Object getCloudTalkAppStatus(CloudDeviceSDKDTO dto) {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        ArrayList<Map<String, Object>> list = new ArrayList<>();
        List<String> paramList=null;
        if (dto.getDeviceUnique().length()!=0){
            paramList=Arrays.asList(dto.getDeviceUnique());
        }
        Map<String, Object> paramMap = new HashMap<>();
        for(String a :paramList){
            paramMap.put(a,a);
        }
        try {
            //传入设备id，一个或者多个，和设备类型 一体式人脸识别平板
            OperateDeviceManageGetPageDTO operateDeviceManageGetPageDTO = new OperateDeviceManageGetPageDTO();
            operateDeviceManageGetPageDTO.setDeviceUnique(dto.getDeviceUnique());
            operateDeviceManageGetPageDTO.setDeviceType(dto.getDeviceType());
            OperateDeviceManageInfoAllVO  deviceByPage = iOperateDeviceManageServiceClient.getDeviceByPage(operateDeviceManageGetPageDTO);
            Page<OperateDeviceManageInfoVO> page = deviceByPage.getPage();
           if (page.getRows().size()!=0){
               List<OperateDeviceManageInfoVO> rows = page.getRows();
               for (OperateDeviceManageInfoVO OperateDeviceManageInfoVO : rows) {
                   Map<String, Object> map = new HashMap<>();
                   if (paramMap.containsKey(OperateDeviceManageInfoVO.getDeviceUnique())){
                       map.put("deviceName",OperateDeviceManageInfoVO.getDeviceName());
                       map.put("deviceUnique",OperateDeviceManageInfoVO.getDeviceUnique());
                       map.put("isOnline",OperateDeviceManageInfoVO.getIsOnline());
                       list.add(map);
                   }

               }

           }


        } catch (Exception e) {
            request.setAttribute("exception", e.toString());
            throw new DataAccessException("【SDK_云对讲getCloudTalkAppStatus】获取在线状态失败", e);
        }
        Map<String, Object> signMap = new HashMap<>();
        signMap.put("data", JSON.toJSONString(list));
        return new SDKMessageVO(BaseErrorCodeEnum.SUCCESS.getErrorCode(), dto.getRequestId(), dto.getResponseTimestamp(),
                Md5EncryptUtil.getSDKV2Md5(signMap, dto.getRequestId(), dto.getResponseTimestamp(), dto.getAppSecret()), list);
    }
*/
}
